package com.example.forumsystem.services.impl;


import com.example.forumsystem.common.AppResult;
import com.example.forumsystem.common.ResultCode;
import com.example.forumsystem.dao.UserMapper;
import com.example.forumsystem.exception.ApplicationException;
import com.example.forumsystem.model.User;
import com.example.forumsystem.services.IUserService;
import com.example.forumsystem.utils.MD5Util;
import com.example.forumsystem.utils.StringUtil;
import com.example.forumsystem.utils.UUIDUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.File;
import java.util.Date;

@Service
@Slf4j
public class UserServiceImpi implements IUserService {
    @Resource
    private UserMapper userMapper;

    @Override
    public void createNormalUser(User user) {
        // 非空校验
        if(StringUtil.isEmpty(user.getUserName())
                || StringUtil.isEmpty(user.getNickName())
                || StringUtil.isEmpty(user.getPassword())
                || StringUtil.isEmpty(user.getSalt())) {
            // 打印日志
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());

            // 抛异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));

        }
        // 根据用户名查询用户信息
        User existUser = userMapper.selectByUserName(user.getUserName());
        // 校验用户是否存在
        if (existUser != null) {
            log.info(ResultCode.FAILED_USER_EXISTS.toString() + " userInof: " + existUser);
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_EXISTS));
        }
        // 填充默认值
        if (user.getGender() == null) {
            user.setGender((byte) 2);
        }
        // 填充默认值
        user.setArticleCount(0);
        user.setIsAdmin((byte) 0);
        user.setState((byte) 0);
        user.setDeleteState((byte) 0);
        // 填充时间
        Date date = new Date();
        user.setCreateTime(date);
        user.setUpdateTime(date);
        Integer row = userMapper.insertSelective(user);
        if(row <= 0) {
            log.info(ResultCode.FAILED_CREATE.toString() + " userName: " + user.getUserName());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_CREATE));
        }
        log.info("新增用户成功! " + "userName="+ user.getUserName() + " userId=" + user.getId());
    }

    @Override
    public User selectByUserName(String userName) {
        if (StringUtil.isEmpty(userName)) {
            log.warn("用户名为空");
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        User user = userMapper.selectByUserName(userName);
        return user;
    }

    @Override
    public User login(String userName, String passwrod) {
        // 参数校验
        if(StringUtil.isEmpty(userName) || StringUtil.isEmpty(passwrod)) {
            log.info("用户名或密码为空, userName: "+ userName);
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }

        // 根据用户名查询用户
        User user = selectByUserName(userName);
        if(user == null) {
            log.info("用户名不存在: " + userName);
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_LOGIN));
        }

        // 校验密码
        if(!MD5Util.verifyPassword(passwrod,user.getSalt(),user.getPassword())) {
            // 校验失败
            log.info("密码校验失败, userName: " + user.getUserName());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_LOGIN));
        }
        log.info( user.getUserName() + "登入成功! ");
        return user;
    }


    @Override
    public User selectById(Long id) {
        // 参数校验
        if(id == null) {
            // 校验失败,抛异常
            log.info("id 为空: " + ResultCode.FAILED_PARAMS_VALIDATE);
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        User user = userMapper.selectByPrimaryKey(id);
        System.out.println(user.toString());

        // 根据id获取用户
        return user;
    }


    @Override
    public void addOneArticleCountById(Long id) {
        //校验参数
        if(id == null || id <= 0) {
            // 打印日志
            log.info(ResultCode.FAILED_PARAMS_VALIDATE.toString() + "user id = " + id);
            // 抛异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        // 根据用户id 获取用户信息
        User user = userMapper.selectByPrimaryKey(id);
        if(user == null || user.getId() <= 0) {
            // 打印日志
            log.info(ResultCode.FAILED_USER_NOT_EXISTS.toString());
            // 抛异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS));
        }


        // 参数校验成功,构建user对象
        User updateUser = new User();
        updateUser.setId(user.getId());
        updateUser.setArticleCount(user.getArticleCount() + 1);

        // 修改用户文章个数
        int row = userMapper.updateByPrimaryKeySelective(updateUser);

        if(row != 1) {
            // 打印日志
            log.info(ResultCode.FAILED_UPDATE.toString() + ", row:" + row);
            // 抛异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_UPDATE));
        }

        // 到这里就是新增成了
        log.info(ResultCode.SUCCESS.toString() + "用户文章数量+1成功, userId: " + user.getId());
    }

    @Override
    public void subOneArticleCountById(Long id) {
        //校验参数
        if(id == null || id <= 0) {
            // 打印日志
            log.info(ResultCode.FAILED_PARAMS_VALIDATE.toString() + "user id = " + id);
            // 抛异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        // 根据用户id 获取用户信息
        User user = userMapper.selectByPrimaryKey(id);
        if(user == null || user.getId() <= 0) {
            // 打印日志
            log.info(ResultCode.FAILED_USER_NOT_EXISTS.toString());
            // 抛异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS));
        }


        // 参数校验成功,构建user对象
        User updateUser = new User();
        updateUser.setId(user.getId());
        updateUser.setArticleCount(user.getArticleCount() -1);
        // 判断文章个数是否下于0
        if(user.getArticleCount() < 0) {
            user.setArticleCount(0);
        }


        // 修改用户文章个数
        int row = userMapper.updateByPrimaryKeySelective(updateUser);
        // 校验
        if(row != 1) {
            // 打印日志
            log.info(ResultCode.FAILED_UPDATE.toString() + ", row:" + row);
            // 抛异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_UPDATE));
        }

        // 到这里就是-1成功了
        log.info(ResultCode.SUCCESS.toString() + "用户文章数量-1成功, userId: " + user.getId());
    }

    @Override
    public void modifyInfo(User user) {
        // 根据userId获取user对象
        User existsUser = userMapper.selectByPrimaryKey(user.getId());
        if (existsUser == null) {
            // 打印日志
            log.info(ResultCode.FAILED_USER_NOT_EXISTS.toString());
            // 抛异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS));
        }
        // 设置标志位
        Boolean checkAttr = false;
        // 创建update修改对象
        User updateUser = new User();
        updateUser.setId(user.getId());
        // 进行参数校验

        // 1. 校验用户名
        if(!StringUtil.isEmpty(user.getUserName())) {

            // 校验新用户名是否与原用户名相同
            if(user.getUserName().equals(existsUser.getUserName())) {
                // 打印日志
                log.info("新用户名与原用户名相同");
                // 抛异常
                throw new ApplicationException(AppResult.failed("新用户名与原用户名相同"));
            }


            // 修改用户名不为空,并且与原用户名不相同
            User checkUser = userMapper.selectByUserName(user.getUserName());
            if(checkUser != null) {
                // 打印日志
                log.info(ResultCode.FAILED_USER_EXISTS.toString());
                // 抛异常
                throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_EXISTS));
            }
            updateUser.setUserName(user.getUserName());
            checkAttr = true;
        }
        // 校验昵称
        if(!StringUtil.isEmpty(user.getNickName()) && !user.getNickName().equals(existsUser.getNickName())) {
            updateUser.setNickName(user.getNickName());
            checkAttr = true;
        }

        // 校验性别
        if(user.getGender() != null && user.getGender() != existsUser.getGender()) {
            updateUser.setGender(user.getGender());
            // 校验性别的合法性
            if(updateUser.getGender() > 2 || updateUser.getGender() < 0) {
                updateUser.setGender((byte) 2);
            }
            checkAttr = true;
        }


        // 校验邮箱
        if(!StringUtil.isEmpty(user.getEmail()) && !user.getEmail().equals(existsUser.getEmail())) {
            updateUser.setEmail(user.getEmail());
            checkAttr = true;
        }
        log.info("existsUser" + existsUser);

        // 校验电话
        if(!StringUtil.isEmpty(user.getPhoneNum()) && !user.getPhoneNum().equals(existsUser.getPhoneNum())) {
            updateUser.setPhoneNum(user.getPhoneNum());
            checkAttr = true;
        }
        // 校验个人简介
        if(!StringUtil.isEmpty(user.getRemark()) && !user.getRemark().equals(existsUser.getRemark())) {
            updateUser.setRemark(user.getRemark());
            checkAttr = true;
        }
        log.info("existsUser" + existsUser);
        log.info("checkAttr" + checkAttr);
        // 校验标准非, 没有需要修改的地方, 就进入抛异常
        if (checkAttr == false) {
            // 打印日志
            log.info(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            // 抛异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        log.info("existsUser" + existsUser);

        // 调用DAO
        int row = userMapper.updateByPrimaryKeySelective(updateUser);
        // 判断成功与否
        if(row != 1) {
            // 打印日志
            log.info(ResultCode.ERROR_SERVICES.toString());
            // 抛异常
            throw new ApplicationException(AppResult.failed(ResultCode.ERROR_SERVICES));
        }
    }

    @Override
    public void modifyPwd(Long id, String oldPassword, String newPassword) {
        // 校验用户
        User user = userMapper.selectByPrimaryKey(id);
        if(user == null || user.getId() <= 0) {
            // 打印日志
            log.info(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            // 抛异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        // 获取密文
        String existsEncipherPasswrod = user.getPassword();
        // 获取旧盐
        String existsSalt = user.getSalt();

        // 校验前端传的密码是否有效
        String oldEncipherPasswrod = MD5Util.md5Salt(oldPassword, existsSalt);
        if(!oldEncipherPasswrod.equalsIgnoreCase(existsEncipherPasswrod)) {
            // 打印日志
            log.info(ResultCode.FAILED_UPDATE_PASSWROD.toString());
            // 抛异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_UPDATE_PASSWROD));
        }

        // 生成新盐值
        String newSalt = UUIDUtil.salt32();
        // 根据新密码生成新密文
        String newEncipherPasswrod = MD5Util.md5Salt(newPassword, newSalt);

        // 创建新对象
        User updateUser = new User();
        updateUser.setId(user.getId());
        updateUser.setSalt(newSalt);
        updateUser.setPassword(newEncipherPasswrod);
        // 调用DAO修改密码
        int row = userMapper.updateByPrimaryKeySelective(updateUser);
        // 校验修改结果
        if(row != 1) {
            // 打印日志
            log.info(ResultCode.ERROR_SERVICES.toString() + ",修改密码失败, userId: " + user.getId());
            // 抛异常
            throw new ApplicationException(AppResult.failed(ResultCode.ERROR_SERVICES));
        }
    }

    @Override
    public void upload(Long userId, String newName) {
        User user = new User();
        user.setId(userId);
        System.out.println("./image/" + newName);
        user.setAvatarUrl("./image/" + newName);
        userMapper.updateByPrimaryKeySelective(user);
    }

}
